Shell学习笔记09-case条件语句的应用

GO


case条件语句相当于多分支的if/elif/else条件语句,但是它比这些条件语句看起来更规范更公正,常被应用于实现系统服务启动脚本等企业应用场景中。

在case语句中,程序会将case获取的变量的值与表达式部分的值1值2值3等逐个进行比较,如果获取的变量值和某个值(例如值1)相匹配,就会执行值(例如值1)后面对应的指令(例如指令1,其可能是一组指令),直到执行到双分号(;;)才会停止,然后再跳出case语句主体,执行case语句(即esac字符)后面的其他命令。

如果没有找到匹配变量的任何值,则执行*)后面的指令(通常是给使用者的使用提示),直到遇到双分号(;;)(此处的双分号可以省略)或esac结束,这部分相当于if多分支语句中最后的else语句部分。另外,case语句中表达式对应值的部分,还可以使用管道等更多功能来匹配。

1. case条件语句的语法

case条件语句的语法格式为:

1
2
3
4
5
6
7
8
9
10
11
case "变量名" in
1)
指令1...
;;
2)
指令2...
;;
...
*)
指令3...
esac

说明:当变量的值等于值1时,执行指令1;等于值2时执行指令2,以此类推;如果都不符合,则执行*)后面的指令,即指令3。此外,注意不同行内容的缩进距离。

2. case条件语句实践

范例1:根据用户的输入判断用户输入的是哪个数字

如果用户输入的是1-9的任意数字,则输出对应输入的数字;如果是其它数字及字符,则返回输入不正确的提示并退出程序。

  • 参考答案1:使用case语句实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #!/bin/bash
    read -p "Plaease input a number:" ans
    case "$ans" in
    1)
    echo "The num you input is 1"
    ;;
    2)
    echo "The num you input is 2"
    ;;
    [3-9]) #<==如果用户输入的信息为3-9中的任意数字,注意范围匹配的正则写法,则执行下面的echo输出
    echo "The num you input is $ans"
    ;;
    *) #<==如果不匹配上面任何一个值,则执行下面的echo输出
    echo "Please input [0-9] int"
    exit;
    esac #<==esac语句结束前的最后一个值匹配,可以省略双分号
  • 参考答案2:使用if语句实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/bin/bash
    read -p "Please input a number:" ans
    if [ $ans -eq 1 ];then
    echo "the num you input is 1"
    elif [ $ans -eq 2 ];then
    echo "the num you input is 2"
    elif [ $ans -ge 3 -a $ans -le 9 ];then
    echo "the num you input is $ans"
    else
    echo "the num you input must be [1-9]"
    exit
    fi

对比case语句和if语句,会发现case语句更简洁更规范,if语句看起来则要更复杂一些。

3. 实践:给输出的字符串加颜色

3.1. 给输出的字符串加颜色的基础知识

Linux命令行中给字体加颜色的命令为:

  • echo -e "\E[1;31m红色字theshu\E[0m"
  • echo -e "\033[31m红色字theshu\033[0m"

在上述命令中:

  • echo -e可以识别转义字符,这里将识别特殊字符的含义,并输出
  • \E可以使用\033替代
  • [1数字1表示加粗显示(可以加不同的数字,以代表不同的意思,详细信息可用man console_codes获得)
  • 31m表示为红色字体,可以换成不通的数字,以代表不同的意思
  • 红色字theshu代表待设置的内容
  • [0m表示关闭所有属性,可以换成不同的数字,以代表不同的意思

有关ANSI控制码的说明如下:

  • \33[0m表示关闭所有属性
  • \33[1m表示设置高亮度
  • \33[4m表示下划线
  • \33[5m表示闪烁
  • \33[7m表示反显
  • \33[8m表示消隐
  • \33[30m\33[37m表示设置前景色
  • \33[40m\33[47m表示设置背景色

console codes的更多知识可以参考man console_codes,普通读者了解即可。


在Linux脚本中,可以通过echo-e参数,结合特殊的数字给不同的字符加上颜色并显示。

范例:给内容加上不同的颜色

  • 内容的颜色可用数字表示,范围为30~37,每个数字代表一种颜色。代码如下:
    1
    2
    3
    4
    5
    6
    7
    8
    echo -e "\033[30m 黑色字 theshu trainning \033[0m" #<==30m表示黑色字
    echo -e "\033[31m 红色字 theshu trainning \033[0m" #<==31m表示红色字
    echo -e "\033[32m 绿色字 theshu trainning \033[0m" #<==32m表示绿色字
    echo -e "\033[33m 棕色字 theshu trainning \033[0m" #<==33m表示棕色字
    echo -e "\033[34m 蓝色字 theshu trainning \033[0m" #<==34m表示蓝色字
    echo -e "\033[35m 洋红色字 theshu trainning \033[0m" #<==35m表示洋红色字
    echo -e "\033[36m 蓝绿色字 theshu trainning \033[0m" #<==36m表示蓝绿色字
    echo -e "\033[37m 白色字 theshu trainning \033[0m" #<==37m表示白色字

说明:不同的数字对应不同的字体颜色,详情参见系统帮助(man console_codes

范例:通过定义变量的方式给字体加颜色(推荐使用的方式)

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
RED_COLOR='\E[1;31m'
GREEN_COLOR='\E[1;32m'
YELLOW_COLOR='\E1;33m'
BLUE_COLOR='\E[1;34m'
PINK='\E[1;35m'
RES='\E[0m'
echo -e "${RED_COLOR}====red color====${RES}"
echo -e "${YELLOW_COLOR}====yellow color====${RES}"
echo -e "${BLUE_COLOR}====blue color====${RES}"
echo -e "${GREEM_COLOR}====green color====${RES}"
echo -e "${PINK}====pink color====${RES}"

3.2. 结合case语句给输出的字符串加颜色

请开发一个给指定内容加指定颜色的脚本。

要求:使用case语句及通过脚本传入指定内容和指定颜色,在脚本命令行传2个参数,给指定的内容(第一个参数)加指定的颜色(第二个参数)。

  • 实现脚本如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    #!/bin/bash
    RED_COLOR='\E[1;31m'
    GREEN_COLOR='\E[1;32m'
    YELLOW_COLOR='\E[1;33m'
    BLUE_COLOR='\E[1;34m'
    PINK_COLOR='\E[1;35m'
    RES='\E[0m'
    #<==以上部分将颜色字符定义为变量,方便后续使用
    if [ $# -ne 2 ];then
    echo "Usage $0 content {red|yellow|blue|green|pink}"
    exit
    fi
    case "$2" in
    red|RED)
    echo -e "${RED_COLOR}$1${RES}"
    ;;
    yellow|YELLOW)
    echo -e "${YELLOW_COLOR}$1${RES}"
    ;;
    green|GREEN)
    echo -e "${GREEN_COLOR}$1${RES}"
    ;;
    blue|BLUE)
    echo -e "${BLUE_COLOR}$1${RES}"
    ;;
    pink|PINK)
    echo -e "${PINK_COLOR}$1${RES}"
    ;;
    *)
    echo "Usage $0 content {red|yellow|blue|green|pink}"
    exit
    esac
  • 如果脚本中要加颜色的内容很多,还可以专门写一个给内容加颜色的函数,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    #!/bin/bash
    plus_color(){
    RED_COLOR='\E[1;31m'
    GREEN_COLOR='\E[1;32m'
    YELLOW_COLOR='\E[1;33m'
    BLUE_COLOR='\E[1;34m'
    PINK_COLOR='\E[1;35m'
    RES='\E[0m'
    if [ $# -ne 2 ];then
    echo "Usage $0 content {red|yellow|blue|green|pink}"
    exit
    fi
    case "$2" in
    red|RED)
    echo -e "${RED_COLOR}$1${RES}"
    ;;
    yellow|YELLOW)
    echo -e "${YELLOW_COLOR}$1${RES}"
    ;;
    green|GREEN)
    echo -e "${GREEN_COLOR}$1${RES}"
    ;;
    blue|BLUE)
    echo -e "${BLUE_COLOR}$1${RES}"
    ;;
    pink|PINK)
    echo -e "${PINK_COLOR}$1${RES}"
    ;;
    *)
    echo "Usage $0 content {red|yellow|blue|green|pink}"
    exit
    esac
    }
    plus_color "I" red
    plus_color "am" green
    plus_color "theshu" blue
  • 本题更专业更规范的实现脚本如下,此脚本为全函数模块化、标准化、专业化的实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #!/bin/bash
    #<==定义加颜色函数addColor
    function addColor(){
    RED_COLOR='\E[1;31m'
    GREEN_COLOR='\E[1;32m'
    YELLOW_COLOR='\E[1;33m'
    BLUE_COLOR='\E[1;34m'
    PINK_COLOR='\E[1;35m'
    RES='\E[0m'
    if [ $# -ne 2 ];then
    echo "Usage $0 content {red|yellow|blue|green|pink}"
    exit
    fi
    case "$2" in
    red|RED)
    echo -e "${RED_COLOR}$1${RES}"
    ;;
    yellow|YELLOW)
    echo -e "${YELLOW_COLOR}$1${RES}"
    ;;
    green|GREEN)
    echo -e "${GREEN_COLOR}$1${RES}"
    ;;
    blue|BLUE)
    echo -e "${BLUE_COLOR}$1${RES}"
    ;;
    pink|PINK)
    echo -e "${PINK_COLOR}$1${RES}"
    ;;
    *)
    echo "Usage $0 content {red|yellow|blue|green|pink}"
    exit
    esac
    }
    #<==定义主函数main
    function main(){
    addColor $1 $2
    }
    #<==执行主函数
    main $*

3.3. 给输出的字符串加背景颜色

给输出的字符串加不同的背景颜色。字的背景颜色对应的数字的范围为40~47,代码如下:

1
2
3
4
5
6
7
8
echo -e "\033[40;37m 黑底白字 theshu \033[0m" #<==40m表示黑色背景
echo -e "\033[41;37m 红底白字 theshu \033[0m" #<==41m表示红色背景
echo -e "\033[42;37m 绿底白字 theshu \033[0m" #<==42m表示绿色背景
echo -e "\033[43;37m 棕底白字 theshu \033[0m" #<==43m表示棕色背景,和黄色背景相近
echo -e "\033[44;37m 蓝底白字 theshu \033[0m" #<==44m表示蓝色背景
echo -e "\033[45;37m 洋红底白字 theshu \033[0m" #<==45m表示洋红色背景,和紫色背景相近
echo -e "\033[46;37m 蓝绿底白字 theshu \033[0m" #<==46m表示蓝绿色色背景,和浅蓝色背景相近
echo -e "\033[47;30m 白底黑字 theshu \033[0m" #<==47m表示白色背景

说明:不同的数字所对应的背景字体颜色见系统帮助(man console_codes

4. 总结

  • case语句和if条件语句的适用性
    • case语句比较适合变量值较少且为固定的数字或字符串集合的情况,如果变量的值是已知固定的start|stop|restart等元素,那么采用case语句来实现就比较合适。
  • case语句和if语句的常见应用场景
    • case主要是写服务的启动脚本,一般情况下,传参不同且具有少量的字符串,其适用范围较窄。
    • if就是取值判断、比较,应用面比case更广。几乎所有的case语句都可以用if条件语句来实现。
  • case语句的特点及优势
    case语句就相当于多分支的if/elif/else语句,但是case语句的优势是更规范、易读。

OK

0%